package com.ruoyi.optimization.common;

import org.springframework.beans.BeanUtils;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;

/**
 * 一根原材料
 */
public class Material implements Cloneable { // 确保 Material 类也实现 Cloneable 接口
    private Integer length; // 原材料标准长度
    private Integer remaining; // 当前剩余可用长度
    private List<Integer> parts; // 已装载的零件列表

    public Material(Integer length, Integer count) {
        this.length = length;
        this.remaining = length;
        this.parts = new ArrayList<>();
    }

    // 添加零件并优化排列（核心方法）
    public boolean addPart(Integer partLength) {
        if (remaining >= partLength) {
            parts.add(partLength);
            remaining -= partLength;
            optimizeOrder(); // 添加后立即优化排列
            return true;
        }
        return false; // 空间不足时返回失败
    }

    // FFD启发式优化：降序排列零件减少余料
    private void optimizeOrder() {
        parts.sort(Comparator.reverseOrder());
        Integer tempRemain = length;
        List<Integer> newParts = new ArrayList<>();
        // 重新计算有效零件组合
        for (Integer p : parts) {
            if (tempRemain >= p) {
                newParts.add(p);
                tempRemain -= p;
            }
        }
        parts.clear();
        parts.addAll(newParts);
        remaining = tempRemain;
    }

    // 克隆方法（修复TypeError的关键）
    public Material clone() {
        Material material = null;
        try {
            material = (Material) super.clone();
        } catch (CloneNotSupportedException e) {
            throw new RuntimeException(e);
        }
        BeanUtils.copyProperties(this, material);
        // 深拷贝 parts 列表
        material.parts = new ArrayList<>(this.parts);
        return material;
    }

    public void setParts(List<Integer> parts) {
        this.parts = parts;
    }

    public Integer getLength() {
        return length;
    }

    public void setLength(Integer length) {
        this.length = length;
    }

    public Integer getRemaining() {
        return remaining;
    }

    public void setRemaining(Integer remaining) {
        this.remaining = remaining;
    }

    public List<Integer> getParts() {
        return parts;
    }
}